home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / plugins / mapmicrobrush.py < prev    next >
Text File  |  2004-01-05  |  9KB  |  305 lines

  1. """   QuArK  -  Quake Army Knife
  2.  
  3. Python code to implement the various Duplicator styles.
  4. """
  5. #
  6. # Copyright (C) 1996-99 Armin Rigo
  7. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  8. # FOUND IN FILE "COPYING.TXT"
  9. #
  10.  
  11. #$Header: /cvsroot/quark/runtime/plugins/mapmicrobrush.py,v 1.9 2003/12/18 21:51:46 peter-b Exp $
  12.  
  13.  
  14. #
  15. # Feel free to add your own styles here, or better
  16. # in a new plug-in that looks like this one.
  17. #
  18.  
  19. Info = {
  20.    "plug-in":       "Micro-Brush Finder",
  21.    "desc":          "Standard Duplicator styles.",
  22.    "date":          "10 Feb 2001",
  23.    "author":        "tiglari",
  24.    "author e-mail": "tiglari@hexenworld.net",
  25.    "quark":         "Version 6.1" }
  26.  
  27.  
  28. from quarkpy.maputils import *
  29. import quarkpy.mapmenus
  30. import quarkpy.mapcommands
  31. import quarkpy.dlgclasses
  32. import mapmadsel
  33. import quarkx
  34.  
  35. #
  36. # A `Live Edit' dialog.  Note the action buttons, which
  37. #   use a rather convoluted technique to produce their
  38. #   effects (when a button is bushed,
  39. #   quarkpy.qmacro.MACRO_zapview is executed with an index
  40. #   saying which, this calls the appropriate function of the
  41. #   dialog, which was attached to the editor when executed).
  42. #
  43. # A ListBox would be better than a ComboBox for data entry,
  44. #   but FormCFG.pas doesn't at the moment support ListBoxes.
  45. #   In principle, this could be fixed.
  46. #
  47.  
  48. class MicroKillDlg (quarkpy.dlgclasses.LiveEditDlg):
  49.     #
  50.     # dialog layout
  51.     #
  52.  
  53.     endcolor = AQUA
  54.     size = (220,160)
  55.     dfsep = 0.35
  56.  
  57.     dlgdef = """
  58.         {
  59.         Style = "9"
  60.         Caption = "Microbrush hunter-killer"
  61.  
  62.         micros: = {
  63.           Typ = "C"
  64.           Txt = "Micros:"
  65.           Items = "%s"
  66.           Values = "%s"
  67.           Hint = "These are the brushes that are too thin.  Pick one," $0D " then push buttons on row below for action."
  68.         }
  69.  
  70.           
  71.         sep: = { Typ="S" Txt=""}
  72.  
  73.         buttons: = {
  74.         Typ = "PM"
  75.         Num = "3"
  76.         Macro = "zapview"
  77.         Caps = "IDA"
  78.         Txt = "Actions:"
  79.         Hint1 = "Inspect the chosen one"
  80.         Hint2 = "Delete the chosen one"
  81.         Hint3 = "Kill them all"
  82.         }
  83.  
  84.         num: = {
  85.           Typ = "EF1"
  86.           Txt = "# found"
  87.         }
  88.  
  89.         thin: = {
  90.           Typ = "EF001"
  91.           Txt = "too thin: "
  92.           Hint = "Brushes thinner than this will be nominated for removal"
  93.         }
  94.         
  95.         sep: = { Typ="S" Txt=""}
  96.  
  97.         exit:py = {Txt="" }
  98.     }
  99.     """
  100.  
  101.     def inspect(self):
  102.         index = eval(self.chosen)
  103.         #
  104.         # FIXME: dumb hack, revise mapmadsel
  105.         #
  106.         m = qmenu.item("",None)
  107.         m.object=self.pack.thinnies[index]
  108.         mapmadsel.ZoomToMe(m)
  109.         mapmadsel.SelectMe(m)
  110.  
  111.     def zap(self):
  112.         index = eval(self.chosen)
  113.         undo=quarkx.action()
  114.         thin = self.pack.thinnies[index]
  115.         undo.exchange(thin,None)
  116.         self.editor.ok(undo,'delete microbrush')
  117.         self.pack.thinnies.remove(thin)   
  118.         self.src["micros"]=''
  119.         #
  120.         # This seems to need to be called to get the dialog
  121.         #   to reset itself with the new data (not quite sure
  122.         #   why it doesn't happen automatically here, but it
  123.         #   dosnt seem to)
  124.         #
  125.         self.datachange(self.dlg)
  126.  
  127.     def zapall(self):
  128.         undo=quarkx.action()
  129.         for brush in self.pack.thinnies:
  130.             undo.exchange(brush,None)
  131.         self.editor.ok(undo,'delete microbrushes')
  132.         self.src["micros"]=''
  133.         self.datachange(self.dlg)
  134.  
  135. #
  136. # Define the zapview macro here, put the definition into
  137. #  quarkpy.qmacro, which is where macros called from delphi
  138. #  live.
  139. #
  140. def macro_zapview(self, index=0):
  141.     editor = mapeditor()
  142.     if editor is None: return
  143.     if index==1:
  144.         editor.microbrushdlg.inspect()
  145.     elif index==2:
  146.         editor.microbrushdlg.zap()
  147.     elif index==3:
  148.         editor.microbrushdlg.zapall()
  149.         
  150. quarkpy.qmacro.MACRO_zapview = macro_zapview
  151.  
  152. #
  153. # For a face, for each other different face, the vertex furthest
  154. #  away from the other face must be far enough away/
  155. #
  156. def brushIsThin(brush, thick):
  157.     for face in brush.faces:
  158.         for face2 in brush.faces:
  159.             if not face2 is face:
  160.                 n = face2.normal
  161.                 d = face2.dist
  162.                 sep = 0.0
  163.                 for vert in face.verticesof(brush):
  164.                     sep=max(sep,abs(vert-projectpointtoplane(vert,n,d*n,n)))
  165.                 if sep<thick:
  166.                         return 1
  167.     return 0                
  168.                 
  169. def getThin(thin, editor):
  170.     thinnies = []
  171.     for brush in editor.Root.findallsubitems("",":p"):
  172.         if brushIsThin(brush,thin):
  173.             thinnies.append(brush)
  174.     return thinnies
  175.     
  176. def thinClick(m):
  177.     editor=mapeditor()
  178.     thinnies=[]
  179.  
  180.     thin = quarkx.setupsubset(SS_MAP, "Options")["thinsize"]
  181.     if thin==None:
  182.         thin="1.0"
  183.  
  184.     for brush in editor.Root.findallsubitems("",":p"):
  185.         if brushIsThin(brush,eval(thin)):
  186.             thinnies.append(brush)
  187.     
  188.     #
  189.     # Here we start the Live Edit dialog invocation sequence.
  190.     #  Data to be tracked during the life of the dialog goes
  191.     #  here.
  192.     #
  193.     class pack:
  194.         "stick stuff in this"
  195.     pack.thinnies=thinnies
  196.     pack.thin=thin
  197.     pack.seen=0
  198.       
  199.     #
  200.     # This loads the relevant data into the dialog, gets
  201.     #  recalled after changes.
  202.     #
  203.     def setup(self, pack=pack, editor=editor):
  204.         self.pack=pack
  205.         #
  206.         # Part of the convolution for the buttons, to communicate
  207.         #  which objects methods should be called when one pushed.
  208.         # Cleaned up in onclosing below.
  209.         #
  210.         editor.microbrushdlg=self
  211.         
  212.         #
  213.         # Names and list-indexes of thin brushes
  214.         #
  215.         ran = range(len(pack.thinnies))
  216.         pack.slist = map(lambda obj,num :"%d) %s"%(num+1,obj.shortname), pack.thinnies, ran)
  217.         pack.klist = map(lambda d:`d`, ran)
  218.  
  219.         #
  220.         #  wtf doesn't this work, item loads but function is trashed
  221.         #
  222. #        self.src["micros"] = pack.klist[0]
  223.         self.src["micros$Items"] = "\015".join(pack.slist)
  224.         self.src["micros$Values"] = "\015".join(pack.klist)
  225.         if not pack.seen and len(ran)>1:
  226.             self.src["micros"] = '0'
  227.             self.chosen = '0'
  228.             pack.seen = 1
  229.         elif len(ran)==0:
  230.             self.src["micros"] = ''
  231.             self.chosen = ''
  232.         
  233.         #
  234.         # Note the commas, EF..1 controls take 1-tuples as data
  235.         #
  236.         self.src["num"]=len(pack.klist),
  237.         self.src["thin"]=eval(pack.thin),
  238.  
  239.     #
  240.     # When data is entered, this gets executed.
  241.     #
  242.     def action(self, pack=pack, editor=editor):
  243.        src = self.src
  244.        #
  245.        # note what's been chosen
  246.        #
  247.        self.chosen = src["micros"]
  248.        #
  249.        # see if thinness threshold has been changed
  250.        #
  251.        newthin, = self.src["thin"]
  252.        if newthin!=pack.thin:
  253.            if newthin==1.0:
  254.                quarkx.setupsubset(SS_MAP, "Options")["thinsize"]=None
  255.            else:
  256.                quarkx.setupsubset(SS_MAP, "Options")["thinsize"]="%f2"%newthin
  257.            pack.thinnies=getThin(newthin, editor)
  258.            pack.thin="%.2f"%newthin
  259.            
  260.     #
  261.     # Cleanup when dialog closes (not needed if no mess has
  262.     #  been created)
  263.     #
  264.     def onclosing(self,editor=editor):
  265.         del editor.microbrushdlg
  266.         
  267.     #
  268.     # And here's the invocation. 2nd arg is a label for storing
  269.     #  position info in setup.qrk.
  270.     #
  271.     MicroKillDlg(quarkx.clickform, 'microkill', editor, setup, action, onclosing)
  272.  
  273.  
  274. quarkpy.mapsearch.items.append(qmenu.item('Find &Microbrushes', thinClick,
  275.  "|Find Microbrushes:\n\nThis function identifies brushes that are suspiciously small, at least in one dimension.", "intro.mapeditor.menu.html#searchmenu"))
  276.  
  277. #$Log: mapmicrobrush.py,v $
  278. #Revision 1.9  2003/12/18 21:51:46  peter-b
  279. #Removed reliance on external string library from Python scripts (second try ;-)
  280. #
  281. #Revision 1.8  2003/03/21 05:47:45  cdunde
  282. #Update infobase and add links
  283. #
  284. #Revision 1.7  2002/05/21 10:24:12  tiglari
  285. #make collected item numbering start with 1)
  286. #
  287. #Revision 1.6  2002/05/21 09:16:16  tiglari
  288. #fix problems with selection dialog: the first of two with identical names was
  289. # always being chosen, and first item on list wouldn't load
  290. #
  291. #Revision 1.5  2001/06/17 21:10:57  tiglari
  292. #fix button captions
  293. #
  294. #Revision 1.4  2001/06/16 03:19:05  tiglari
  295. #add Txt="" to separators that need it
  296. #
  297. #Revision 1.3  2001/05/21 11:56:51  tiglari
  298. #a bit of cleaning
  299. #
  300. #Revision 1.2  2001/02/11 08:04:15  tiglari
  301. #comments added, some cosmetics
  302. #
  303. #Revision 1.1  2001/02/11 06:44:17  tiglari
  304. #Version 1
  305. #